#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  

#define MAXARGS 20    // 最大参数数量  
#define ARGLEN 100    // 每个参数的最大长度  

/**  
 * 执行命令  
 * @param arglist 参数列表  
 * @return 不返回，成功执行execvp后进程映射到新程序  
 */  
int execute(char *arglist[]) {  
    execvp(arglist[0], arglist);  // 使用execvp执行命令  
    perror("execvp failed");       // 如果execvp失败，输出错误信息  
    exit(1);                       // 退出程序  
}  

/**  
 * 创建一个新的字符串，移除末尾的换行符并分配内存  
 * @param buf 输入缓冲区  
 * @return 新分配的字符串  
 */  
char *makestring(char *buf) {  
    char *cp;  

    buf[strlen(buf) - 1] = '\0';         // 移除换行符  
    cp = malloc(strlen(buf) + 1);        // 分配内存  
    if (cp == NULL) {                     // 检查内存分配是否成功  
        fprintf(stderr, "no memory\n");  
        exit(1);  
    }  
    strcpy(cp, buf);                      // 拷贝字符串  
    return cp;                            // 返回新字符串  
}  

int main() {  
    char *arglist[MAXARGS + 1];  // 参数列表，最后一个元素为NULL  
    int numargs;                 // 当前参数数量  
    char argbuf[ARGLEN];         // 输入缓冲区  

    numargs = 0;  
    while (numargs < MAXARGS) {  // 允许最多MAXARGS个参数  
        printf("Arg[%d]? ", numargs);  
        // 读取输入，并检查是否为空行  
        if (fgets(argbuf, ARGLEN, stdin) && *argbuf != '\n') {  
            arglist[numargs++] = makestring(argbuf);  // 添加参数到列表  
        } else {  
            if (numargs > 0) {             // 如果有参数，执行命令  
                arglist[numargs] = NULL;   // 参数列表末尾设置为NULL  
                execute(arglist);          // 执行命令  
                numargs = 0;               // 重置参数计数  
            }  
        }  
    }  
    return 0;  
}